package ca.llsutherland.squash.domain;

import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import ca.llsutherland.squash.utils.Constants;

public class Clock implements Serializable {

    private static final long serialVersionUID = 1L;
    private Calendar calendar = Calendar.getInstance();
    private SimpleDateFormat formatter = null;

    public Clock(int year, int month, int day, int hour, int minutes, int seconds) {
        initialize(year, month, day, hour, minutes, seconds);
    }

    public Clock(long time) {
        calendar.setTimeInMillis(time);
    }

    private void initialize(int year, int month, int day, int hour, int minute, int seconds) {
        calendar.setLenient(false);
        calendar.set(Calendar.YEAR, year);
        calendar.set(Calendar.MONTH, month);
        calendar.set(Calendar.DAY_OF_MONTH, day);
        calendar.set(Calendar.HOUR_OF_DAY, hour);
        calendar.set(Calendar.MINUTE, minute);
        calendar.set(Calendar.SECOND, seconds);
    }
    
    public Date getDate() {
        return calendar.getTime();
    }
    
    public String format(String pattern) {
        if (formatter == null) {
            formatter = new SimpleDateFormat();
            formatter.setTimeZone(TimeZone.getDefault());
        }
        formatter.applyPattern(pattern);
        return formatter.format(calendar.getTime());
    }
    
    @Override
    public String toString() {
        return format(Constants.DATE_FORMAT_YYYY_M_D_HH_MM_SS);
    }

    public Long getTimeInMillis() {
        return Long.valueOf(calendar.getTimeInMillis());
    }
    
    @Override
    public boolean equals(Object obj) {
        Clock clockObj = (Clock)obj;
        return yearEquals(clockObj) && monthEquals(clockObj) && dayEquals(clockObj) && hourEquals(clockObj) && minuteEquals(clockObj) && secondEquals(clockObj);
    }
    
    private boolean secondEquals(Clock clockObj) {
        return this.calendar.get(Calendar.SECOND) == clockObj.calendar.get(Calendar.SECOND);
    }
    
    private boolean minuteEquals(Clock clockObj) {
        return this.calendar.get(Calendar.MINUTE) == clockObj.calendar.get(Calendar.MINUTE);
    }
    
    private boolean hourEquals(Clock clockObj) {
        return this.calendar.get(Calendar.HOUR) == clockObj.calendar.get(Calendar.HOUR);
    }
    
    private boolean dayEquals(Clock clockObj) {
        return this.calendar.get(Calendar.DAY_OF_MONTH) == clockObj.calendar.get(Calendar.DAY_OF_MONTH);
    }

    private boolean monthEquals(Clock clockObj) {
        return this.calendar.get(Calendar.MONTH) == clockObj.calendar.get(Calendar.MONTH);
    }

    private boolean yearEquals(Clock clockObj) {
        return this.calendar.get(Calendar.YEAR) == clockObj.calendar.get(Calendar.YEAR);
    }

    public boolean isAfter(Clock otherDate) {
        return this.getTimeInMillis() > otherDate.getTimeInMillis();
    }

    public boolean isBefore(Clock otherDate) {
        return this.getTimeInMillis() < otherDate.getTimeInMillis();
    }

    public boolean hasPassed() {
        return this.getTimeInMillis() > Calendar.getInstance().getTimeInMillis();
    }
}
